package pokerAI.PokerAI;
import java.io.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Random;
import java.lang.Math;
import java.lang.String;

import java.io.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Random;
import java.lang.Math;
import java.lang.String;

public class Hand{
        private Card[] cards;
        int count;                              // amount of cards in hand
        private int[] value;
       
        public Hand(){
                cards = new Card[2];
                count = 0;
                value = new int[6];
                for(int i=0; i<6; i++)
                {
                        value[i] = 0;
                }
        }
        public Hand(Card[] c)
        {
                cards = new Card[5];
                for(int i=0; i<5; i++)
                {
                        cards[i] = new Card(c[i].getNumber(), c[i].getSuit());
                }
        value = new int[6];
        for(int i=0; i<6; i++)
        {
                value[i] = 0;
        }
        calcValue();
        }
       
        public void receiveCard( Card c ){
                if ( count < 2 ){
                        cards[count] = c;
                        count++;
                }
                if(count == 2)
                {
                        calcValue();
                }
        }
        public int compareTo(Hand that)
    {
        for (int x=0; x<6; x++)
        {
            if (this.value[x]>that.value[x])
                return 1;
            else if (this.value[x]<that.value[x])
                return -1;
        }
        return 0; //if hands are equal
    }
       
        public Card viewCard( int i ){
                Card c = new Card();
                if (i < count){
                        c = cards[i];
                }
                // if they are requestion a card that they do not own
                // let them know and then give them the topmost card they have
                else{
                        System.out.println("That Card does not exist, top card is");
                        c = cards[count-1];
                }
                return c;
        }      
               
        public void setCard( int i, Card c ){
                cards[i] = c;
        }
       
        public int getAmountOfCards(){
                return count;
        }
       
        public boolean isHandEmpty(){
                boolean b = false;
                if (count == 0){
                        b = true;
                }
                return b;
        }
        public String toString()
        {
                String toReturn = "Your best hand is as follows...\n";
                toReturn += cards[0].toString() + " \n";
                toReturn += cards[1].toString() + " \n";
                toReturn += cards[2].toString() + " \n";
                toReturn += cards[3].toString() + " \n";
                toReturn += cards[4].toString() + " \n";
                toReturn += value[0] + " \n";
                toReturn += value[1] + " \n";
                toReturn += value[2] + " \n";
                toReturn += value[3] + " \n";
                toReturn += value[4] + " \n";
                toReturn += value[5] + " \n";
               
                return toReturn;
        }
        private void calcValue()
    {
        int[] ranks = new int[14];
        //miscellaneous cards that are not otherwise significant
        int[] orderedRanks = new int[5];
        boolean flush=true, straight=false;
        int sameCards=1,sameCards2=1;
        int largeGroupRank=0,smallGroupRank=0;
        int index=0;

        for (int x=0; x<=13; x++)
        {
            ranks[x]=0;
        }
        for (int x=0; x<=4; x++)
        {
            ranks[ cards[x].getNumber() ]++;
        }
        for (int x=0; x<4; x++) {
            if ( cards[x].getSuit() != cards[x+1].getSuit() )
                flush=false;
        }

        for (int x=13; x>=1; x--)
        {
                 if (ranks[x] > sameCards)
                 {
                     if (sameCards != 1)
                     //if sameCards was not the default value
                     {
                         sameCards2 = sameCards;
                         smallGroupRank = largeGroupRank;
                     }

                     sameCards = ranks[x];
                     largeGroupRank = x;

                 } else if (ranks[x] > sameCards2)
                 {
                     sameCards2 = ranks[x];
                     smallGroupRank = x;
                 }
        }

        if (ranks[1]==1) //if ace, run this before because ace is highest card
        {
            orderedRanks[index]=14;
            index++;
        }

        for (int x=13; x>=2; x--)
        {
            if (ranks[x]==1)
            {
                orderedRanks[index]=x; //if ace
                index++;
            }
        }
       
        for (int x=1; x<=9; x++)
        //can't have straight with lowest value of more than 10
        {
            if (ranks[x]==1 && ranks[x+1]==1 && ranks[x+2]==1 &&
                ranks[x+3]==1 && ranks[x+4]==1)
            {
                straight=true;
                break;
            }
        }

        if (ranks[10]==1 && ranks[11]==1 && ranks[12]==1 &&
            ranks[13]==1 && ranks[1]==1) //ace high
        {
            straight=true;
        }
       
        for (int x=0; x<=5; x++)
        {
            value[x]=0;
        }


        //start hand evaluation
        if ( sameCards==1 ) {
            value[0]=1;
            value[1]=orderedRanks[0];
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==2 && sameCards2==1)
        {
            value[0]=2;
            value[1]=largeGroupRank; //rank of pair
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
            value[4]=orderedRanks[2];
            value[5]=orderedRanks[3];
        }


        if (sameCards==2 && sameCards2==2) //two pair
        {
            value[0]=3;
            //rank of greater pair
            value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank;
            value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank;
            value[3]=orderedRanks[0];  //extra card
        }

        if (sameCards==3 && sameCards2!=2)
        {
            value[0]=4;
            value[1]= largeGroupRank;
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
        }

        if (straight && !flush)
        {
            value[0]=5;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (flush && !straight)
        {
            value[0]=6;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==3 && sameCards2==2)
        {
            value[0]=7;
            value[1]=largeGroupRank;
            value[2]=smallGroupRank;
        }

        if (sameCards==4)
        {
            value[0]=8;
            value[1]=largeGroupRank;
            value[2]=orderedRanks[0];
        }

        if (straight && flush)
        {
            value[0]=9;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }
    }
}

